package com.mzpai.web.controller;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.gexin.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.mzpai.product.constant.PayConstants;
import com.mzpai.product.exception.ProductResExceptionCode;
import com.mzpai.product.model.StoreOrder;
import com.mzpai.product.model.SystemStoreDdfBill;
import com.mzpai.product.model.User;
import com.mzpai.product.model.WstPayments;
import com.mzpai.product.service.StoreDdfBillService;
import com.mzpai.product.service.StoreOrderService;
import com.mzpai.product.service.UserService;
import com.mzpai.product.service.WstPaymentsService;
import com.mzpai.product.util.HttpClient;
import com.mzpai.product.util.WXPayUtil;
import com.mzpai.product.vo.PayMentsClientVo;
import com.mzpai.product.vo.UserInfoVo;
import com.mzpai.product.vo.WstPaymentsVo;
import com.mzpai.util.DateUtil;
import com.mzpai.util.StringUtils;
import com.mzpai.vo.ResponseVo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
 *
 * 支付方式配置查询
 *
 */
@Api(value = "支付方式接口")
@RestController
@RequestMapping("/wstPayments")
public class WstPaymentsController extends BaseController {

	@Autowired 
	private WstPaymentsService wstPaymentsService;
	@Autowired 
	private StoreOrderService storeOrderService;
	@Autowired 
	private UserService userService;
	
	private static final String wxurl = "https://api.mch.weixin.qq.com/pay/micropay";
	private static final String wxQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
	private static final String appId = "wxd36f77843d0e2615";
	private static final String mchId = "1600336452";
	private static final String keysCer = "3Q3DXErcU3yyfR29oVt8ATVJyvliRiV4";
	
	@Autowired
	private StoreDdfBillService storeDdfBillService;
	
	/** 
	*
	* 查询支付方式列表 
	* @throws Exception
	*/
	@ApiOperation(value = "查询支付方式列表 ")
	@RequestMapping(value = "/getWstPaymentList",method = {RequestMethod. POST ,RequestMethod. GET})
	@ResponseBody
	public ResponseVo<WstPaymentsVo> getWstPaymentList() throws Exception {
		
		ResponseVo<WstPaymentsVo> res=new ResponseVo<WstPaymentsVo>();
		Map<String, Object> searchMap = new HashMap<String,Object>();
		List<String> isChannelList=new ArrayList<String>();
		isChannelList.add("2");
		isChannelList.add("3");
		searchMap.put("enabled", 1);
		searchMap.put("isChannelList", isChannelList);
		List<WstPayments> list = wstPaymentsService.getList(searchMap);
		WstPaymentsVo wstPaymentsVo=null;
		if(list!=null && !list.isEmpty()){
			wstPaymentsVo=new WstPaymentsVo();
			List<WstPayments> onlinePaymentList=new ArrayList<WstPayments>();
			List<WstPayments> offlinePaymentList=new ArrayList<WstPayments>();
			for(WstPayments wp:list){
				String isOnline=wp.getIsOnline();
				if(isOnline.equals(PayConstants.IS_ONLINE_PAY)){
					onlinePaymentList.add(wp);
				}else{
					offlinePaymentList.add(wp);
				}
			}
			wstPaymentsVo.setOnlinePaymentList(onlinePaymentList);
			wstPaymentsVo.setOfflinePaymentList(offlinePaymentList);
		}
		res.setResult(wstPaymentsVo);
		return res;
	}
	
	
	/** 
	* 调用接口发起收入
	* @throws Exception
	*/
	@ApiOperation(value = "向用户发起收款")
	@RequestMapping(value = "/payMentsToClient")
	@ResponseBody
	public ResponseVo<Boolean> payMentsToClient(@RequestParam(value = "payMentsStr", required = true) String payMentsStr) throws Exception {
		ResponseVo<Boolean> res=new ResponseVo<Boolean>();
		res.setResult(false);
		logger.info("msg1=向用户发起收款，参数={}", payMentsStr);
		try{
			PayMentsClientVo vo = JSONObject.parseObject(payMentsStr, PayMentsClientVo.class);
			if(StringUtils.isBlank(vo.getAuthCode()) ||  StringUtils.isBlank(vo.getOrderId())) {
				res.setCode(-1);
				res.setMessage("参数信息不全，无法发起收款");
				return res;
			}
			
			Integer storeId=vo.getStoreId();
			if(storeId==null){
				res.setCode(ProductResExceptionCode.STOREID_NULL.getCode());
				res.setMessage(ProductResExceptionCode.STOREID_NULL.getMessage());
				return res;
			}
			
			StoreOrder orderInfo = storeOrderService.getOrderByCode(vo.getOrderId());
			Integer userId=orderInfo.getUid();
			User user = userService.queryByUserId(userId);
			
			//当时订单使用的抵扣金总额
			BigDecimal usedDdfPrice=orderInfo.getUsedDdfPrice();
			Double usedDdfPriceDouble=usedDdfPrice.doubleValue();
			  
			  
//			User user = userService.queryByUserText(vo.getUserEncryptData());
//			if(!userId.equals(orderInfo.getUid() + "")) {
//				res.setCode(-1);
//				res.setMessage("订单不是此用户订单，请核对！");
//				return res;
//			}
			//拉起支付时 校验抵扣金是否充足  更新对应实际支付金额
			BigDecimal totalDeductedGold=userService.getTotalDeducteGold(storeId, userId);
			Double totalDeductedGoldDouble=totalDeductedGold.doubleValue();
			
			if(usedDdfPriceDouble>0 && totalDeductedGoldDouble<usedDdfPriceDouble){
				res.setCode(ProductResExceptionCode.DEDUCT_DONOT_USE.getCode());
				res.setMessage(ProductResExceptionCode.DEDUCT_DONOT_USE.getMessage());
				return res;
			}
			String xml = getBWSKString(vo, orderInfo);
			String reponStr = HttpClient.postXML(wxurl, xml);
			logger.info("调用接口返回数据信息={}", reponStr);
			if(StringUtils.isNoneBlank(reponStr)) {
				Map<String, String> map = StringUtils.xmlToMap(reponStr);
				if("SUCCESS".equals(map.get("result_code"))) {
					//更新订单状态
					updateOrderState(orderInfo);
					
				} else if("USERPAYING".equals(map.get("err_code"))) {
					//用户需要支付密码
					Thread.sleep(5*1000);
					
					//微信订单号信息
					if(queryWxOrderState(orderInfo.getOrderId())) {
						//更新订单状态
						updateOrderState(orderInfo);
					} else {
						res.setCode(-1);
						res.setMessage("用户支付失败,请重试！");
						res.setResult(false);
						return res;
					}
					
					
				} else {
					logger.info("msg1=用户={}, 支付时间={}， 支付订单={}， 失败信息={}",user.getAccount(), DateUtil.formatTime(new Date()), orderInfo.getOrderId(), map.get("err_code_des"));
					res.setCode(-1);
					res.setMessage("用户支付失败,请重试！");
					res.setResult(false);
					return res;
				}
				
			} else {
				res.setCode(-1);
				res.setMessage("用户支付失败,请重试！");
				res.setResult(false);
				return res;
			}
			
		} catch(Exception e) {
			logger.error("msg1=异常信息={}", e);
		}
		return res;
	}
	
	
	private boolean queryWxOrderState(String orderId) throws Exception {
		String random = UUID.randomUUID().toString().replace("-", "");
		String str = WXPayUtil.getWXCXxml(appId, mchId, orderId, random, null);
		String signStr = WXPayUtil.getWxSignString(str, keysCer);
		String mtp =  WXPayUtil.getWXCXxml(appId, mchId, orderId, random, signStr);
		String reponStr = HttpClient.postXML(wxQueryUrl, mtp);
		Map<String, String> map = StringUtils.xmlToMap(reponStr);
		if("SUCCESS".equals(map.get("trade_state"))) {
			return true;
		}
		return false;
	}


	private void updateOrderState(StoreOrder orderInfo) {
		storeOrderService.updatePayOrder(orderInfo);
	}


	private String getBWSKString(PayMentsClientVo vo, StoreOrder orderInfo) throws Exception{
		String random = UUID.randomUUID().toString().replace("-", "");
		String str = WXPayUtil.getWXSKxml(appId, mchId,orderInfo.getOrderId(),vo.getAuthCode(), orderInfo.getPayPrice().multiply(new BigDecimal(100)).intValue(), random, null);
		String signStr = WXPayUtil.getWxSignString(str, keysCer);
		return WXPayUtil.getWXSKxml(appId, mchId,orderInfo.getOrderId(),vo.getAuthCode(), orderInfo.getPayPrice().multiply(new BigDecimal(100)).intValue(), random, signStr);

	}
	
}